package cn.com.chengmandian.bike.service.impl;

import cn.com.chengmandian.bike.model.*;
import cn.com.chengmandian.bike.mapper.EbMemberPayMapper;
import cn.com.chengmandian.bike.service.*;
import cn.com.chengmandian.core.common.constants.CommonConstant;
import cn.com.chengmandian.core.common.utils.BillNoUtil;
import cn.com.chengmandian.core.redis.cache.AgentCacheService;
import cn.com.chengmandian.core.redis.cache.AgentParamCacheService;
import cn.com.chengmandian.core.redis.service.RedisService;
import cn.com.chengmandian.core.web.pojo.AgentInfo;
import cn.com.chengmandian.service.bike.constants.*;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.math.BigDecimal;
import java.util.*;
import static cn.com.chengmandian.service.bike.constants.MemberPayBusinessTypeEnum.DEPOSIT;


/**
 * <p>
 * 电单车运营-支付记录 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2021-12-15
 */
@Service
@Slf4j
public class EbMemberPayServiceImpl extends ServiceImpl<EbMemberPayMapper, EbMemberPay> implements IEbMemberPayService {

    @Autowired
    private IEbMemberWalletService memberWalletService;

    @Autowired
    private IEbMemberCardService memberCardService;

    @Autowired
    private IEbMemberMoneyService memberMoneyService;

    @Autowired
    private IEbMemberInfoService memberInfoService;

    @Autowired
    private IEbMemberDepositService memberDepositService;

    @Autowired
    private IEbRechargeActivityService rechargeActivityService;

    @Autowired
    private IEbRideOrderService rideOrderService;

    @Autowired
    private IEbMessageInfoService messageInfoService;

    @Autowired
    private IEbRechargeRecordService rechargeRecordService;

    @Autowired
    private AgentCacheService agentCacheService;

    @Autowired
    private IEbMemberComboRecordService memberComboRecordService;

    @Autowired
    private IEbDepositRecordService depositRecordService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private AgentParamCacheService agentParamCacheService;

    @Autowired
    private IEbRidePenaltyService ridePenaltyService;


    @Override
    public EbMemberPay createPay(Integer areaId, Integer memberId, MemberPayBusinessTypeEnum businessType, Integer businessId, BigDecimal money, Integer payChannel) {
        return this.createPay(areaId, memberId, businessType, businessId, money, payChannel, null);
    }

    @Override
    public EbMemberPay createPay(Integer areaId, Integer memberId, MemberPayBusinessTypeEnum businessType, Integer businessId, BigDecimal money, Integer payChannel, String businessData) {
        EbMemberPay memberPay = new EbMemberPay();
        memberPay.setAreaId(areaId);
        memberPay.setPayNo(BillNoUtil.getSimpleNo("MP-"));
        memberPay.setMemberId(memberId);
        memberPay.setBusinessType(businessType.getCode());
        memberPay.setBusinessId(businessId);
        memberPay.setMoney(money);
        memberPay.setPayChannel(payChannel);
        memberPay.setStatus(MemberPayStatusEnum.READY.getCode());
        memberPay.setMchPortal(CommonConstant.ONE);
        memberPay.setIsShare(-1);
        memberPay.setBusinessData(businessData);
        this.save(memberPay);
        return memberPay;
    }

    @Override
    @Transactional
    public void paySuccessByNo(String payNo, String channelNo) {
        EbMemberPay memberPay = this.getOne(new LambdaQueryWrapper<EbMemberPay>()
                .eq(EbMemberPay::getPayNo, payNo)
                .last("limit 1"));
        Assert.notNull(memberPay, "订单不存在");
        Assert.isTrue(memberPay.getStatus().equals(MemberPayStatusEnum.READY.getCode()), "订单状态不正确");
        this.paySuccessByPay(memberPay, channelNo);
    }

    @Override
    @Transactional
    public void paySuccessByPay(EbMemberPay memberPay, String channelNo) {
        LambdaUpdateWrapper<EbMemberPay> memberPayLambdaUpdateWrapper = new LambdaUpdateWrapper<EbMemberPay>()
                .set(EbMemberPay::getChannelNo, channelNo)
                .set(EbMemberPay::getStatus, MemberPayStatusEnum.PAID.getCode())
                .set(EbMemberPay::getPayTime, new Date())
                .eq(EbMemberPay::getId, memberPay.getId());

        EbMemberPay ebMemberPay = this.getById(memberPay.getId());

        AgentInfo agentInfo = agentCacheService.getAgent(ebMemberPay.getAgentId().toString());
        // 手续费比例
        BigDecimal feeRatio = BigDecimal.ZERO;
        // 手续费金额
        BigDecimal feeMoney = BigDecimal.ZERO;
        // 处理微信/支付宝 支付手续费
        if (agentInfo != null) {
            if (PayChannelEnum.WXPAY.getCode().equals(memberPay.getPayChannel()) && agentInfo.getWxFeeRatio() != null) {
                feeRatio = agentInfo.getWxFeeRatio();
                feeMoney = agentInfo.getWxFeeRatio().multiply((memberPay.getMoney() == null ? BigDecimal.ZERO : memberPay.getMoney())).setScale(2, BigDecimal.ROUND_HALF_UP);
            } else if (PayChannelEnum.ALIPAY.getCode().equals(memberPay.getPayChannel()) && agentInfo.getAliFeeRatio() != null) {
                feeRatio = agentInfo.getAliFeeRatio();
                feeMoney = agentInfo.getAliFeeRatio().multiply((memberPay.getMoney() == null ? BigDecimal.ZERO : memberPay.getMoney())).setScale(2, BigDecimal.ROUND_HALF_UP);
            }
        }
        memberPayLambdaUpdateWrapper.set(EbMemberPay::getFeeRatio, feeRatio)
                .set(EbMemberPay::getFeeMoney, feeMoney);
        this.update(memberPayLambdaUpdateWrapper);

        // 钱包充值
        if (memberPay.getBusinessType().equals(MemberPayBusinessTypeEnum.WALLET.getCode())) {
            memberWalletService.updateBalance(memberPay.getAreaId(), memberPay.getMemberId(), memberPay.getMoney(), MemberMoneyBusinessTypeEnum.CHARGE, memberPay.getId(), MemberMoneyOperationTypeEnum.USER);
            EbRechargeActivity rechargeActivity = rechargeActivityService.getActivity(memberPay.getAreaId(), memberPay.getMoney());
            String ext = "";
            if (rechargeActivity != null && rechargeActivity.getGiftMoney() != null && rechargeActivity.getGiftMoney().compareTo(new BigDecimal(0)) > 0) {
                memberWalletService.updateBalance(memberPay.getAreaId(), memberPay.getMemberId(), rechargeActivity.getGiftMoney(), MemberMoneyBusinessTypeEnum.ADD_GIFT, rechargeActivity.getId(), MemberMoneyOperationTypeEnum.USER);
                ext = "并额外获得" + rechargeActivity.getGiftMoney().doubleValue() + "元充值礼金，";
                rechargeActivityService.update(new LambdaUpdateWrapper<EbRechargeActivity>()
                        .set(EbRechargeActivity::getTimes, (rechargeActivity.getTimes() + 1))
                        .eq(EbRechargeActivity::getId, rechargeActivity.getId()));
            }
            // 充值记录
            rechargeRecordService.createRecord(memberPay.getId(), memberPay.getAreaId(), memberPay.getMemberId(), rechargeActivity, memberPay.getMoney());
            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 " + DateUtil.now() + " 充值成功" + memberPay.getMoney().doubleValue() + "元，" + ext + "感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.WALLET, null);

            // 购买骑行卡
        } else if (memberPay.getBusinessType().equals(MemberPayBusinessTypeEnum.CARD.getCode())) {
            if (memberPay.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
                memberWalletService.updateBalance(memberPay.getAreaId(), memberPay.getMemberId(), memberPay.getMoney(), MemberMoneyBusinessTypeEnum.CARD_COST, memberPay.getId(), MemberMoneyOperationTypeEnum.USER);
            } else {
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.CARD_COST, memberPay.getId(), MemberMoneyOperationTypeEnum.USER, memberPay.getMoney());
            }
            EbMemberCard memberCard = memberCardService.createCard(memberPay.getId(), memberPay.getMemberId(), memberPay.getBusinessId(), memberPay.getMoney(), CommonConstant.ONE, null);
            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 " + DateUtil.now() + " 购买骑行卡成功，本次消费" + memberPay.getMoney().doubleValue() + "元，有效期至 " + DateUtil.format(memberCard.getExpireTime(), "yyyy-MM-dd HH:mm:ss") + " ，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.CARD, memberCard.getId());
            // 通过骑行订单待支付页面 购买骑行卡
            String businessData = memberPay.getBusinessData();
            if(StrUtil.isNotBlank(businessData)) {
                JSONObject jsonBusinessData = JSONObject.parseObject(businessData);
                Integer rideOrderId = jsonBusinessData.getInteger("rideOrderId");
                if(rideOrderId != null) {
                    // 自动消耗购买的骑行开
                    rideOrderService.orderConsumeMemberCard(rideOrderId, memberCard.getId(), UserTypeEnum.MEMBER.getCode());
                }
            }

            // 充值押金
        } else if (memberPay.getBusinessType().equals(DEPOSIT.getCode())) {
            if (memberPay.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
                memberWalletService.updateBalance(memberPay.getAreaId(), memberPay.getMemberId(), memberPay.getMoney(), MemberMoneyBusinessTypeEnum.PAY_DEPOSIT, memberPay.getId(), MemberMoneyOperationTypeEnum.USER);
            } else {
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.PAY_DEPOSIT, memberPay.getId(), MemberMoneyOperationTypeEnum.USER, memberPay.getMoney());
            }
            memberInfoService.payDeposit(memberPay.getMemberId(), memberPay.getMoney());
            depositRecordService.createRecord(memberPay.getMemberId(), memberPay.getMoney(), memberPay.getId());

            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 " + DateUtil.now() + " 充值押金成功，本次支付" + memberPay.getMoney().doubleValue() + "元，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.DEPOSIT, null);

            // 购买免押卡
        } else if (memberPay.getBusinessType().equals(MemberPayBusinessTypeEnum.DEPOSIT_CARD.getCode())) {
            if (memberPay.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
                memberWalletService.updateBalance(memberPay.getAreaId(), memberPay.getMemberId(), memberPay.getMoney(), MemberMoneyBusinessTypeEnum.PAY_DEPOSIT_CARD, memberPay.getId(), MemberMoneyOperationTypeEnum.USER);
            } else {
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.PAY_DEPOSIT_CARD, memberPay.getId(), MemberMoneyOperationTypeEnum.USER, memberPay.getMoney());
            }
            EbMemberDeposit memberDeposit = memberDepositService.payCard(memberPay.getMemberId(), memberPay.getBusinessId(), memberPay.getMoney());
            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 " + DateUtil.now() + " 购买免押卡成功，本次支付" + memberPay.getMoney().doubleValue() + "元，有效期至 " + DateUtil.format(memberDeposit.getExpireTime(), "yyyy-MM-dd HH:mm:ss") + " ，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.DEPOSIT_CARD, memberDeposit.getId());

        // 支付骑行订单
        } else if (memberPay.getBusinessType().equals(MemberPayBusinessTypeEnum.RIDE_ORDER_PAY.getCode())) {

            BigDecimal payChargeMoney;
            BigDecimal payGiftMoney;
            // 组合消费
            if (memberPay.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
                EbMemberWallet memberWallet = memberWalletService.getMemberWallet(memberPay.getMemberId());
                // 优先扣除赠送金额
                if (memberWallet.getGiftMoney().compareTo(memberPay.getMoney()) >= 0) {
                    payGiftMoney = memberPay.getMoney();
                    payChargeMoney = new BigDecimal(0);
                } else {
                    payGiftMoney = memberWallet.getGiftMoney();
                    payChargeMoney = memberPay.getMoney().subtract(payGiftMoney);
                }
                memberWalletService.updateBalanceForBoth(memberPay.getAreaId(), memberPay.getMemberId(), payChargeMoney, payGiftMoney, MemberMoneyBusinessTypeEnum.RIDE_COST, memberPay.getBusinessId(), MemberMoneyOperationTypeEnum.USER);
            } else {
                payChargeMoney = memberPay.getMoney();
                payGiftMoney = new BigDecimal(0);
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.RIDE_COST, memberPay.getId(), MemberMoneyOperationTypeEnum.USER, memberPay.getMoney());
            }
            rideOrderService.orderPaid(memberPay.getBusinessId(), payChargeMoney, payGiftMoney, UserTypeEnum.MEMBER.getCode());

            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 " + DateUtil.now() + " 支付骑行订单成功，合计消费" + memberPay.getMoney() + "元 ，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.ORDER, memberPay.getBusinessId());


            // 购买会员卡
        } else if (memberPay.getBusinessType().equals(MemberPayBusinessTypeEnum.MEMBER_COMBO_PAY.getCode())) {
            if (memberPay.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
                memberWalletService.updateBalance(memberPay.getAreaId(), memberPay.getMemberId(), memberPay.getMoney(), MemberMoneyBusinessTypeEnum.MEMBER_COMBO_PAY, memberPay.getId(), MemberMoneyOperationTypeEnum.USER);
            } else {
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.MEMBER_COMBO_PAY, memberPay.getId(), MemberMoneyOperationTypeEnum.USER, memberPay.getMoney());
            }
            EbMemberComboRecord memberComboRecord = memberComboRecordService.createRecord(memberPay.getId(), memberPay.getMemberId(), memberPay.getBusinessId(), memberPay.getMoney());
            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 " + DateUtil.now() + " 购买会员卡成功，本次消费" + memberPay.getMoney().doubleValue() + "元，有效期至 " + DateUtil.format(memberComboRecord.getExpireTime(), "yyyy-MM-dd HH:mm:ss") + " ，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.COMBO, memberComboRecord.getId());
            // 缴纳罚款
        } else if (memberPay.getBusinessType().equals(MemberPayBusinessTypeEnum.RIDE_PENALTY_PAY.getCode())) {
            if (memberPay.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
                memberWalletService.updateBalance(memberPay.getAreaId(),
                        memberPay.getMemberId(),
                        memberPay.getMoney(),
                        MemberMoneyBusinessTypeEnum.RIDE_PENALTY_PAY,
                        memberPay.getId(),
                        MemberMoneyOperationTypeEnum.USER);
            } else {
                memberMoneyService.createPay(memberPay.getAreaId(),
                        memberPay.getMemberId(),
                        MemberMoneyBusinessTypeEnum.RIDE_PENALTY_PAY,
                        memberPay.getId(),
                        MemberMoneyOperationTypeEnum.USER,
                        memberPay.getMoney());
            }

            ridePenaltyService.paySuccess(memberPay);

            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 " + DateUtil.now() + " 缴纳骑行订单罚款，本次支付" + memberPay.getMoney().doubleValue() + "元，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.RIDE_PENALTY, memberPay.getBusinessId());
        }

    }

    @Override
    public List<EbMemberPay> getYearPayRecord(Integer memberId) {
        return baseMapper.getYearPayRecord(memberId);
    }

    @Override
    public EbMemberPay getByNo(String payNo) {
        return this.getOne(new LambdaQueryWrapper<EbMemberPay>().eq(EbMemberPay::getPayNo, payNo).last("limit 1"));
    }

}
